<?php

namespace app\admin\model\system;

use app\common\model\TimeModel;
use think\facade\Cache;

/**
 * @property int $id ID
 * @property string $name 插件名称
 * @property string $title 插件标题
 * @property string $icon 图标
 * @property string $description 插件描述
 * @property string $author 作者
 * @property string $author_url 作者主页
 * @property string $config 配置信息
 * @property string $version 版本号
 * @property string $identifier 插件唯一标识符
 * @property int $admin 是否有后台管理 0:关闭,1:开启
 * @property int $create_time 安装时间
 * @property int $sort 排序
 * @property int $status 状态 0:关闭,1:开启
 */
class SystemAddons extends TimeModel
{

    protected $name = "system_addons";

    protected $deleteTime = false;

    public const SELECT_LIST_ADMIN = ['0' => '关闭', '1' => '开启',];

    public const SELECT_LIST_STATUS = ['-2' => '已损坏', '-1' => '未安装', '0' => '未启用', '1' => '已启用',];

    /**
     * 获取所有插件信息
     * @Author jokerfei [ jokerfei377@gmail.com ]
     * @return array|mixed
     */
    public function getAllAddons()
    {
        // 生产模式，获取缓存数据
        if (!config('cache.develop_mode')) {
            $result = cache('addons_all');
            if (empty($result)) {
                $result = self::getAddonsInfo();
                Cache::tag('addons')->set('addons_all', $result);
            }
        }
        else {
            // 开发模式，直接获取最新数据
            $result = self::getAddonsInfo();
        }
        return $result;
    }

    /**
     * 获取插件信息
     * @return array|string
     */
    private function getAddonsInfo()
    {
        // 获取插件目录下的所有插件目录
        $dirs = array_map('basename', glob(ROOT_PATH . 'addons/' . '*', GLOB_ONLYDIR));
        if (!file_exists(ROOT_PATH . 'addons/')) {
            return '插件目录不可读或者不存在';
        }
        // 读取数据库插件表
        $addons = $this->order('sort asc,id desc')->column('*', 'name');

        // 读取未安装的插件
        foreach ($dirs as $plugin) {
            if (!isset($addons[$plugin])) {
                $addons[$plugin]['name'] = $plugin;

                // 获取插件类名
                $class = get_addons_class($plugin);

                // 插件类不存在则跳过实例化
                if (!class_exists($class)) {
                    // 插件的入口文件不存在！
                    $addons[$plugin]['status'] = -2;
                    continue;
                }

                // 实例化插件
                $obj = new $class;
                // 插件插件信息缺失
                if (empty($obj->info)) {
                    // 插件信息缺失！
                    $addons[$plugin]['status'] = -2;
                    continue;
                }

                // 插件插件信息不完整
                if (!$this->checkInfo($obj->info)) {
                    $addons[$plugin]['status'] = -2;
                    continue;
                }

                // 插件未安装
                $addons[$plugin]           = $obj->info;
                $addons[$plugin]['status'] = -1;
            }
        }
        return ['count' => count($addons), 'list' => $addons];
    }

    /**
     * 检查插件插件信息是否完整
     * @param array $info 插件插件信息
     */
    private function checkInfo(array $info)
    {
        $default_item = ['name', 'title', 'author', 'version'];
        foreach ($default_item as $item) {
            if (!isset($info[$item]) || $info[$item] == '') {
                return false;
            }
        }
        return true;
    }

    /**
     * 获取插件配置
     * @param string $name 插件名称
     * @param string $item 指定返回的插件配置项
     * @return array|bool|mixed|string
     */
    public function getConfig(string $name = '', string $item = '')
    {
        // 生产模式，获取缓存数据
        if (!config('cache.develop_mode')) {
            $config = cache('addons_config_' . $name);
            if (!$config) {
                $config = self::where('name', $name)->value('config');
                if (!$config) {
                    return [];
                }
                $config = json_decode($config, true);
                Cache::tag('addons')->set('addons_config_' . $name, $config);
            }
        }
        else {
            // 开发模式，直接获取最新数据
            $config = self::where('name', $name)->value('config');
            $config = json_decode($config, true);
        }
        // 如果需要读取子项
        if (!empty($item)) {
            $items = explode(',', $item);
            if (count($items) == 1) {
                return $config[$item] ?? '';
            }
            $result = [];
            foreach ($items as $item) {
                $result[$item] = $config[$item] ?? '';
            }
            return $result;
        }
        return $config;
    }

    /**
     * 设置插件配置
     * @param string $name 插件名.配置名
     * @param string $value 配置值
     * @return bool
     */
    public static function setConfig(string $name = '', array $value = [])
    {
        $item = '';
        if (strpos($name, '.')) {
            list($name, $item) = explode('.', $name);
        }
        $config = (new SystemAddons)->where('name', $name)->value('config');
        if (!$config) {
            return false;
        }
        $config = json_decode($config, true);
        if ($item === '') {
            // 批量更新
            if (!is_array($value) || empty($value)) {
                // 值的格式错误，必须为数组
                return false;
            }
            $config = array_merge($config, $value);
        }
        else {
            // 更新单个值
            $config[$item] = $value[$item];
        }
        (new SystemAddons)->update(['config' => json_encode($config)], ['name' => $name]);
        // 生产模式，获取缓存数据
        if (!config('cache.develop_mode')) {
            Cache::tag('addons')->set('addons_config_' . $name, $config);
        }
        return true;
    }
}
